{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```bash\n",
    "pip install tensorflow-gpu==1.2\n",
    "pip install dm-sonnet -U\n",
    "pip install tensorflow-probability==0.5.0\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.6/dist-packages/tensorflow/python/util/tf_inspect.py:75: DeprecationWarning: inspect.getargspec() is deprecated since Python 3.0, use inspect.signature() or inspect.getfullargspec()\n",
      "  return _inspect.getargspec(target)\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from sklearn.utils import shuffle\n",
    "import re\n",
    "import time\n",
    "import collections\n",
    "import os\n",
    "from dnc import DNC"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def build_dataset(words, n_words, atleast=1):\n",
    "    count = [['PAD', 0], ['GO', 1], ['EOS', 2], ['UNK', 3]]\n",
    "    counter = collections.Counter(words).most_common(n_words)\n",
    "    counter = [i for i in counter if i[1] >= atleast]\n",
    "    count.extend(counter)\n",
    "    dictionary = dict()\n",
    "    for word, _ in count:\n",
    "        dictionary[word] = len(dictionary)\n",
    "    data = list()\n",
    "    unk_count = 0\n",
    "    for word in words:\n",
    "        index = dictionary.get(word, 0)\n",
    "        if index == 0:\n",
    "            unk_count += 1\n",
    "        data.append(index)\n",
    "    count[0][1] = unk_count\n",
    "    reversed_dictionary = dict(zip(dictionary.values(), dictionary.keys()))\n",
    "    return data, count, dictionary, reversed_dictionary"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "len from: 500, len to: 500\n"
     ]
    }
   ],
   "source": [
    "with open('english-train', 'r') as fopen:\n",
    "    text_from = fopen.read().lower().split('\\n')[:-1]\n",
    "with open('vietnam-train', 'r') as fopen:\n",
    "    text_to = fopen.read().lower().split('\\n')[:-1]\n",
    "print('len from: %d, len to: %d'%(len(text_from), len(text_to)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "vocab from size: 1935\n",
      "Most common words [(',', 564), ('.', 477), ('the', 368), ('and', 286), ('to', 242), ('of', 220)]\n",
      "Sample data [482, 483, 78, 6, 137, 484, 10, 226, 787, 14] ['rachel', 'pike', ':', 'the', 'science', 'behind', 'a', 'climate', 'headline', 'in']\n"
     ]
    }
   ],
   "source": [
    "concat_from = ' '.join(text_from).split()\n",
    "vocabulary_size_from = len(list(set(concat_from)))\n",
    "data_from, count_from, dictionary_from, rev_dictionary_from = build_dataset(concat_from, vocabulary_size_from)\n",
    "print('vocab from size: %d'%(vocabulary_size_from))\n",
    "print('Most common words', count_from[4:10])\n",
    "print('Sample data', data_from[:10], [rev_dictionary_from[i] for i in data_from[:10]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "vocab to size: 1461\n",
      "Most common words [(',', 472), ('.', 430), ('tôi', 283), ('và', 230), ('có', 199), ('chúng', 196)]\n",
      "Sample data [84, 22, 668, 73, 10, 389, 110, 34, 81, 299] ['khoa', 'học', 'đằng', 'sau', 'một', 'tiêu', 'đề', 'về', 'khí', 'hậu']\n"
     ]
    }
   ],
   "source": [
    "concat_to = ' '.join(text_to).split()\n",
    "vocabulary_size_to = len(list(set(concat_to)))\n",
    "data_to, count_to, dictionary_to, rev_dictionary_to = build_dataset(concat_to, vocabulary_size_to)\n",
    "print('vocab to size: %d'%(vocabulary_size_to))\n",
    "print('Most common words', count_to[4:10])\n",
    "print('Sample data', data_to[:10], [rev_dictionary_to[i] for i in data_to[:10]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "GO = dictionary_from['GO']\n",
    "PAD = dictionary_from['PAD']\n",
    "EOS = dictionary_from['EOS']\n",
    "UNK = dictionary_from['UNK']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(len(text_to)):\n",
    "    text_to[i] += ' EOS'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_reads = 5\n",
    "num_writes = 1\n",
    "memory_size = 128\n",
    "word_size = 128\n",
    "clip_value = 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Chatbot:\n",
    "    def __init__(self, size_layer, num_layers, embedded_size, \n",
    "                 from_dict_size, to_dict_size, learning_rate, batch_size,\n",
    "                attn_input_feeding=True):\n",
    "        \n",
    "        def attn_decoder_input_fn(inputs, attention):\n",
    "            if attn_input_feeding:\n",
    "                return inputs\n",
    "        \n",
    "        def attention(encoder_out, cell, seq_len, encoder_last_state, reuse=False):\n",
    "            attention_mechanism = tf.contrib.seq2seq.BahdanauAttention(num_units = size_layer, \n",
    "                                                                    memory = encoder_out,\n",
    "                                                                    memory_sequence_length = seq_len)\n",
    "            return tf.contrib.seq2seq.AttentionWrapper(\n",
    "                cell = cell, \n",
    "                attention_mechanism = attention_mechanism,\n",
    "                attention_layer_size = size_layer,\n",
    "                cell_input_fn=attn_decoder_input_fn,\n",
    "                initial_cell_state=encoder_last_state,\n",
    "                alignment_history=False)\n",
    "        \n",
    "        self.X = tf.placeholder(tf.int32, [None, None])\n",
    "        self.Y = tf.placeholder(tf.int32, [None, None])\n",
    "        self.X_seq_len = tf.count_nonzero(self.X, 1, dtype=tf.int32)\n",
    "        self.Y_seq_len = tf.count_nonzero(self.Y, 1, dtype=tf.int32)\n",
    "        access_config = {\n",
    "            \"memory_size\": memory_size,\n",
    "            \"word_size\": word_size,\n",
    "            \"num_reads\": num_reads,\n",
    "            \"num_writes\": num_writes,\n",
    "        }\n",
    "        controller_config = {\n",
    "            \"hidden_size\": size_layer,\n",
    "        }\n",
    "        self.dnc_cell = DNC(access_config=access_config, controller_config=controller_config,\n",
    "                            output_size=size_layer, clip_value=clip_value)\n",
    "        self.dnc_initial = self.dnc_cell.initial_state\n",
    "        \n",
    "        encoder_embeddings = tf.Variable(tf.random_uniform([from_dict_size, embedded_size], -1, 1))\n",
    "        encoder_embedded = tf.nn.embedding_lookup(encoder_embeddings, self.X)\n",
    "        \n",
    "        initial_state = self.dnc_initial(batch_size)\n",
    "        self.encoder_out, self.encoder_state = tf.nn.dynamic_rnn(\n",
    "            cell=self.dnc_cell, inputs=encoder_embedded,\n",
    "            sequence_length=self.X_seq_len, dtype=tf.float32,\n",
    "            initial_state=initial_state)\n",
    "        main = tf.strided_slice(self.Y, [0, 0], [batch_size, -1], [1, 1])\n",
    "        decoder_input = tf.concat([tf.fill([batch_size, 1], GO), main], 1)\n",
    "        # decoder\n",
    "        decoder_embeddings = tf.Variable(tf.random_uniform([to_dict_size, embedded_size], -1, 1))\n",
    "        decoder_cell = attention(self.encoder_out, self.dnc_cell, self.X_seq_len,self.encoder_state)\n",
    "        dense_layer = tf.layers.Dense(to_dict_size)\n",
    "        training_helper = tf.contrib.seq2seq.TrainingHelper(\n",
    "            inputs = tf.nn.embedding_lookup(decoder_embeddings, decoder_input),\n",
    "            sequence_length = self.Y_seq_len,\n",
    "            time_major = False)\n",
    "        training_decoder = tf.contrib.seq2seq.BasicDecoder(\n",
    "            cell = decoder_cell,\n",
    "            helper = training_helper,\n",
    "            initial_state = decoder_cell.zero_state(batch_size=batch_size, dtype=tf.float32),\n",
    "            output_layer = dense_layer)\n",
    "        training_decoder_output, _, _ = tf.contrib.seq2seq.dynamic_decode(\n",
    "            decoder = training_decoder,\n",
    "            impute_finished = True,\n",
    "            output_time_major=False,\n",
    "            maximum_iterations = tf.reduce_max(self.Y_seq_len))\n",
    "        \n",
    "        predicting_helper = tf.contrib.seq2seq.GreedyEmbeddingHelper(\n",
    "                embedding = decoder_embeddings,\n",
    "                start_tokens = tf.tile(tf.constant([GO], dtype=tf.int32), [batch_size]),\n",
    "                end_token = EOS)\n",
    "        predicting_decoder = tf.contrib.seq2seq.BasicDecoder(\n",
    "                cell = decoder_cell,\n",
    "                helper = predicting_helper,\n",
    "                initial_state = decoder_cell.zero_state(batch_size=batch_size, dtype=tf.float32),\n",
    "                output_layer = dense_layer)\n",
    "        predicting_decoder_output, _, _ = tf.contrib.seq2seq.dynamic_decode(\n",
    "                decoder = predicting_decoder,\n",
    "                impute_finished = True,\n",
    "                maximum_iterations = 2 * tf.reduce_max(self.X_seq_len))\n",
    "        self.training_logits = training_decoder_output.rnn_output\n",
    "        self.predicting_ids = predicting_decoder_output.sample_id\n",
    "        masks = tf.sequence_mask(self.Y_seq_len, tf.reduce_max(self.Y_seq_len), dtype=tf.float32)\n",
    "        self.cost = tf.contrib.seq2seq.sequence_loss(logits = self.training_logits,\n",
    "                                                     targets = self.Y,\n",
    "                                                     weights = masks)\n",
    "        self.optimizer = tf.train.AdamOptimizer(learning_rate).minimize(self.cost)\n",
    "        y_t = tf.argmax(self.training_logits,axis=2)\n",
    "        y_t = tf.cast(y_t, tf.int32)\n",
    "        self.prediction = tf.boolean_mask(y_t, masks)\n",
    "        mask_label = tf.boolean_mask(self.Y, masks)\n",
    "        correct_pred = tf.equal(self.prediction, mask_label)\n",
    "        correct_index = tf.cast(correct_pred, tf.float32)\n",
    "        self.accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "size_layer = 256\n",
    "num_layers = 2\n",
    "embedded_size = 128\n",
    "learning_rate = 0.001\n",
    "batch_size = 16\n",
    "epoch = 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:Sonnet nest is deprecated. Please use tf.contrib.framework.nest instead. In addition, `map` is renamed to `map_structure`.\n",
      "WARNING:tensorflow:From /home/husein/addressing.py:35: calling reduce_sum (from tensorflow.python.ops.math_ops) with keep_dims is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "keep_dims is deprecated, use keepdims instead\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.6/dist-packages/numpy/lib/type_check.py:546: DeprecationWarning: np.asscalar(a) is deprecated since NumPy v1.16, use a.item() instead\n",
      "  'a.item() instead', DeprecationWarning, stacklevel=1)\n"
     ]
    }
   ],
   "source": [
    "tf.reset_default_graph()\n",
    "sess = tf.InteractiveSession()\n",
    "model = Chatbot(size_layer, num_layers, embedded_size, len(dictionary_from), \n",
    "                len(dictionary_to), learning_rate,batch_size)\n",
    "sess.run(tf.global_variables_initializer())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def str_idx(corpus, dic):\n",
    "    X = []\n",
    "    for i in corpus:\n",
    "        ints = []\n",
    "        for k in i.split():\n",
    "            ints.append(dic.get(k,UNK))\n",
    "        X.append(ints)\n",
    "    return X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = str_idx(text_from, dictionary_from)\n",
    "Y = str_idx(text_to, dictionary_to)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "def pad_sentence_batch(sentence_batch, pad_int):\n",
    "    padded_seqs = []\n",
    "    seq_lens = []\n",
    "    max_sentence_len = max([len(sentence) for sentence in sentence_batch])\n",
    "    for sentence in sentence_batch:\n",
    "        padded_seqs.append(sentence + [pad_int] * (max_sentence_len - len(sentence)))\n",
    "        seq_lens.append(len(sentence))\n",
    "    return padded_seqs, seq_lens"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch: 1, avg loss: 6.409067, avg accuracy: 0.069264\n",
      "epoch: 2, avg loss: 5.859403, avg accuracy: 0.089123\n",
      "epoch: 3, avg loss: 5.727355, avg accuracy: 0.105535\n",
      "epoch: 4, avg loss: 5.574304, avg accuracy: 0.115628\n",
      "epoch: 5, avg loss: 5.404255, avg accuracy: 0.125040\n",
      "epoch: 6, avg loss: 5.201616, avg accuracy: 0.142058\n",
      "epoch: 7, avg loss: 4.965463, avg accuracy: 0.156692\n",
      "epoch: 8, avg loss: 4.678100, avg accuracy: 0.177471\n",
      "epoch: 9, avg loss: 4.390165, avg accuracy: 0.191455\n",
      "epoch: 10, avg loss: 4.087937, avg accuracy: 0.218103\n",
      "epoch: 11, avg loss: 3.786239, avg accuracy: 0.255813\n",
      "epoch: 12, avg loss: 3.450217, avg accuracy: 0.298548\n",
      "epoch: 13, avg loss: 3.129698, avg accuracy: 0.346350\n",
      "epoch: 14, avg loss: 2.765721, avg accuracy: 0.403250\n",
      "epoch: 15, avg loss: 2.383927, avg accuracy: 0.466340\n",
      "epoch: 16, avg loss: 2.102273, avg accuracy: 0.514097\n",
      "epoch: 17, avg loss: 1.850025, avg accuracy: 0.560891\n",
      "epoch: 18, avg loss: 1.609209, avg accuracy: 0.605419\n",
      "epoch: 19, avg loss: 1.363634, avg accuracy: 0.664943\n",
      "epoch: 20, avg loss: 1.131599, avg accuracy: 0.711184\n"
     ]
    }
   ],
   "source": [
    "for i in range(epoch):\n",
    "    total_loss, total_accuracy = 0, 0\n",
    "    for k in range(0, (len(text_to) // batch_size) * batch_size, batch_size):\n",
    "        index = k+batch_size\n",
    "        batch_x, seq_x = pad_sentence_batch(X[k: index], PAD)\n",
    "        batch_y, seq_y = pad_sentence_batch(Y[k: index], PAD)\n",
    "        predicted, accuracy,loss, _ = sess.run([model.predicting_ids, \n",
    "                                                model.accuracy, model.cost, model.optimizer], \n",
    "                                      feed_dict={model.X:batch_x,\n",
    "                                                model.Y:batch_y})\n",
    "        total_loss += loss\n",
    "        total_accuracy += accuracy\n",
    "    total_loss /= (len(text_to) // batch_size)\n",
    "    total_accuracy /= (len(text_to) // batch_size)\n",
    "    print('epoch: %d, avg loss: %f, avg accuracy: %f'%(i+1, total_loss, total_accuracy))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "row 1\n",
      "QUESTION: and as you can imagine , i hated that moment of ripping with incredible intensity .\n",
      "REAL ANSWER: vì tôi bị bỏng 70 % cơ thể nên mất khoảng 1 tiếng tháo băng .\n",
      "PREDICTED ANSWER: vì tôi huýt gió cùng với cơn đau . \n",
      "\n",
      "row 2\n",
      "QUESTION: and i would try to reason with them and say , &quot; why don &apos;t we try something else ?\n",
      "REAL ANSWER: như bạn có thể tưởng tượng tôi căm ghét cái khoảnh khắc bóc toạc với 1 sức mạnh kinh hồn .\n",
      "PREDICTED ANSWER: và 1 : 1 : bóc rất thích , &quot; &quot; do tốt khắc bộ phim không chưa bao giờ thường quên . \n",
      "\n",
      "row 3\n",
      "QUESTION: why don &apos;t we take it a little longer -- maybe two hours instead of an hour -- and have less of this intensity ? &quot;\n",
      "REAL ANSWER: và tôi sẽ cố gắng lý sự với họ &quot; tại sao chúng ta không thử cách khác ? &quot;\n",
      "PREDICTED ANSWER: và người này vào , không phải đến mọi người không đi trẻ ? \n",
      "\n",
      "row 4\n",
      "QUESTION: and the nurses told me two things .\n",
      "REAL ANSWER: &quot; tại sao chúng ta không làm lâu hơn 1 chút 2 tiếng thay vì 1 tiếng , và nhẹ tay hơn ? &quot;\n",
      "PREDICTED ANSWER: họ có thật lên chất tiếng tốt hơn . \n",
      "\n",
      "row 5\n",
      "QUESTION: they told me that they had the right model of the patient -- that they knew what was the right thing to do to minimize my pain -- and they also told me that the word patient doesn &apos;t mean to make suggestions or to interfere or ...\n",
      "REAL ANSWER: và các y tá nói với tôi 2 điều .\n",
      "PREDICTED ANSWER: và các y tá trở lại có các dòng lỗi . \n",
      "\n",
      "row 6\n",
      "QUESTION: this is not just in hebrew , by the way .\n",
      "REAL ANSWER: họ nói rằng mẫu bệnh nhân đúng mực là những người tin tưởng vào các y tá luôn thao tác đúng để giảm đau tối đa và họ cũng nói rằng bệnh nhân không nên gợi ý hay can thiệp , hoặc ...\n",
      "PREDICTED ANSWER: ý nghĩa là những người này theo google , nhưng ngay khi diybio ra diybio . \n",
      "\n",
      "row 7\n",
      "QUESTION: it &apos;s in every language i &apos;ve had experience with so far .\n",
      "REAL ANSWER: đây không phải bằng chữ hebrew\n",
      "PREDICTED ANSWER: hôm nay , tôi phát hiện sự sáng sinh học của việc đó . \n",
      "\n",
      "row 8\n",
      "QUESTION: and , you know , there &apos;s not much -- there wasn &apos;t much i could do , and they kept on doing what they were doing .\n",
      "REAL ANSWER: nó bằng mọi thứ ngôn ngữ tôi từng biết\n",
      "PREDICTED ANSWER: nếu tôi có một đôi thuyết vi , và điều đó thật sự tuyệt vời . \n",
      "\n",
      "row 9\n",
      "QUESTION: and about three years later , when i left the hospital , i started studying at the university .\n",
      "REAL ANSWER: và , bạn biết đấy , không có nhiều nhiều thứ tôi có thể làm và họ tiếp tục làm công việc của mình .\n",
      "PREDICTED ANSWER: và nhiều khoa học huýt gió cùng với nếu chúng tôi tới khoa học vài mình và biết điều đó . \n",
      "\n",
      "row 10\n",
      "QUESTION: and one of the most interesting lessons i learned was that there is an experimental method that if you have a question you can create a replica of this question in some abstract way , and you can try to examine this question , maybe learn something about the world .\n",
      "REAL ANSWER: và khoảng 3 năm sau , khi tôi ra viện , tôi đã bắt đầu học đại học\n",
      "PREDICTED ANSWER: và khoảng 3 năm sau , khi tôi ra viện , tôi bắt đầu giúp tôi bắt đầu học đại học và từ một dạng của một nhà sinh học và một dạng của một nhà sinh vật điều đó đã rất tuyệt . \n",
      "\n",
      "row 11\n",
      "QUESTION: so that &apos;s what i did .\n",
      "REAL ANSWER: và 1 trong số các bài học thú vị nhất tôi đã học là phương pháp thử nghiệm nghĩa là nếu bạn nghi vấn điều gì , bạn có thể tạo 1 bản mô phỏng nghi vấn một cách trừu tượng , bạn có thể cố gắng kiểm tra nghi vấn , có thể học được chút gì về thế giới .\n",
      "PREDICTED ANSWER: ý tôi không phải đến cơ bắp đây . \n",
      "\n",
      "row 12\n",
      "QUESTION: i was still interested in this question of how do you take bandages off burn patients .\n",
      "REAL ANSWER: đó là những gì tôi đã làm .\n",
      "PREDICTED ANSWER: đó là một cả nghệ này . \n",
      "\n",
      "row 13\n",
      "QUESTION: so originally i didn &apos;t have much money , so i went to a hardware store and i bought a carpenter &apos;s vice .\n",
      "REAL ANSWER: tôi vẫn rất quan tâm đến câu hỏi làm cách nào để tháo băng y tế cho bệnh nhân bỏng .\n",
      "PREDICTED ANSWER: tôi vẫn quan tâm học việc đọc học việc đọc nên vấn đề mà đó . \n",
      "\n",
      "row 14\n",
      "QUESTION: and i would bring people to the lab and i would put their finger in it , and i would crunch it a little bit .\n",
      "REAL ANSWER: ban đầu tôi không có nhiều tiền , vì thế tôi đã đến cửa hàng kim khí và mua 1 cái bàn kẹp thợ mộc .\n",
      "PREDICTED ANSWER: ban đầu tôi không có nước ra nước vào lớp đó không . \n",
      "\n",
      "row 15\n",
      "QUESTION: and i would crunch it for long periods and short periods , and pain that went up and pain that went down , and with breaks and without breaks -- all kinds of versions of pain .\n",
      "REAL ANSWER: sau đó tôi mang mọi người tới phòng thí nhiệm , đặt ngón tay họ vào đó , và tôi kẹp họ 1 chút .\n",
      "PREDICTED ANSWER: sau đó tôi tới 1 chút khắp nước như thế , họ có giai đoạn đó và thật sự rất tuyệt . \n",
      "\n",
      "row 16\n",
      "QUESTION: and when i finished hurting people a little bit , i would ask them , so , how painful was this ? or , how painful was this ?\n",
      "REAL ANSWER: và tôi kẹp trong 1 khoảng thời gian dài và ngắn , cơn đau lúc tăng lúc giảm , có lúc nghỉ ngơi và có lúc không- tất cả các mức độ đau đớn .\n",
      "PREDICTED ANSWER: và tôi kẹp 1 khoảng lúc đó tôi nghe lúc đó , và tôi cố thấm nước như thế nào và tôi sẽ thích sự giải sáng và ngoài điều đó . \n",
      "\n"
     ]
    }
   ],
   "source": [
    "for i in range(len(batch_x)):\n",
    "    print('row %d'%(i+1))\n",
    "    print('QUESTION:',' '.join([rev_dictionary_from[n] for n in batch_x[i] if n not in [0,1,2,3]]))\n",
    "    print('REAL ANSWER:',' '.join([rev_dictionary_to[n] for n in batch_y[i] if n not in[0,1,2,3]]))\n",
    "    print('PREDICTED ANSWER:',' '.join([rev_dictionary_to[n] for n in predicted[i] if n not in[0,1,2,3]]),'\\n')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
